package com.ys.service.business.impl;

import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.ys.enume.base.TransactionTypeEnum;
import com.ys.enume.finance.TcwOperateFrozenRunningEnum;
import com.ys.util.DateUtil;
import com.ys.vo.W;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.alibaba.fastjson.JSON;
import com.ys.dto.AddDto;
import com.ys.entity.business.TpAplusFile;
import com.ys.entity.business.TpAplusSq;
import com.ys.entity.business.TpBoutiqueSiteDetail;
import com.ys.entity.finance.TcwAccountCountForCompany;
import com.ys.entity.flow.YspModel;
import com.ys.entity.hr.ThrOperateCompanyApply;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.mapper.business.TpAplusFileMapper;
import com.ys.mapper.business.TpAplusSqMapper;
import com.ys.service.business.TcwAccountDetailedForCompanyService;
import com.ys.service.business.TpAplusSqService;
import com.ys.service.finance.TcwAccountCountForCompanyService;
import com.ys.service.flow.YspTaskService;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;

@Service("tpAplusSqService")
public class TpAplusSqServiceImpl implements TpAplusSqService {

    @Autowired
    private TpAplusSqMapper tpAplusSqMapper;

    public static Long MENU_ID = 10181L;

    @Autowired
    private YspTaskService yspTaskService;

    @Autowired
    private TpAplusFileMapper tpAplusFileMapper;

    @Autowired
    private TcwAccountDetailedForCompanyService tcwAccountDetailedForCompanyService;

    @Autowired
    private TcwAccountCountForCompanyService tcwAccountCountForCompanyService;




    /**
     * A+申请新增
     * @param params
     * @param subData
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R add(Map<String, Object> params, String subData) throws Exception {
        // 验证订单号
        if (new TpAplusSq().setBid(params.get("bid").toString()).count() > 0) {
            return R.error("该A+申请单号已存在");
        }
        //参数判断
        if (!params.get("serviceFee").toString().matches("\\d+(\\.\\d{0,2})?")){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("服务费格式需要是数值，两位小数点！");
        }else if (params.get("serviceFee").toString().length() > 15){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("服务费格式长度不能大于15");
        }
        if (params.get("applyRequire").toString().length() > 200){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("申请需求长度不允许超过200个字符,保存失败!");
        }
        if (params.get("remark").toString().length() > 200){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("A+备注长度不允许超过200个字符,保存失败!");
        }
        String loginUserId = ShiroUtils.getUserId();
        TsUserChange tsUserChange = new TsUserChange().setUserId(loginUserId).setStatus(1).queryFirst();
        TpAplusSq tpAplusSq = new TpAplusSq();
        tpAplusSq.setBid(params.get("bid").toString());
        tpAplusSq.setVgsBm(params.get("vgsBm").toString());
        tpAplusSq.setVgsJc(params.get("vgsJc").toString());
        tpAplusSq.setVgsMc(params.get("vgsMc").toString());
        tpAplusSq.setCode(params.get("code").toString());
        tpAplusSq.setName(params.get("name").toString());
        tpAplusSq.setCodeMerge(params.get("codeMerge").toString());
        tpAplusSq.setPlatform(params.get("platform").toString());
        tpAplusSq.setRegionName(params.get("regionName").toString());
        tpAplusSq.setCountryName(params.get("countryName").toString());
        tpAplusSq.setBoutiqueId(Long.valueOf(params.get("boutiqueId").toString()));
        tpAplusSq.setFilePath(params.get("filePath").toString());
        tpAplusSq.setServiceFee(new BigDecimal(params.get("serviceFee").toString()));
        tpAplusSq.setApplyRequire(params.get("applyRequire").toString());
        tpAplusSq.setRemark(params.get("remark").toString());
        tpAplusSq.setCreateChangeId(String.valueOf(tsUserChange.getId()));
        tpAplusSq.setEffectStock(FlowEnum.EffectStock.NOT_EFFECT.value);
        tpAplusSq.setStatus(0);
        tpAplusSqMapper.insert(tpAplusSq);

        YsMenu ysMenu = new YsMenu().setId(MENU_ID).queryFirst();
        if (ysMenu.getFlowModelId().longValue() != 0L) {
            YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
            String codeModel = yspModel.getCode();
            String createUserId = ShiroUtils.getUserId();
            yspTaskService.init(codeModel, tpAplusSq.getBid(), createUserId);
        }
        return R.ok(AddDto.gotoEdit("/web/business/tpAplusSq/toEdit?bid=" + tpAplusSq.getBid()));
    }


    /**
     * 修改
     * @param params
     * @param subData
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R update(Map<String, Object> params, String subData) throws Exception {
        TpAplusSq tpAplusSq = JSON.parseObject(JSON.toJSONString(params), TpAplusSq.class);

        //判断是否实在制单中
        Integer flowState = yspTaskService.flowState(tpAplusSq.getBid());

        if (flowState != 0){
            return R.error("A+申请单不是制单中,不允许保存!");
        }

        //参数判断
        if (!params.get("serviceFee").toString().matches("\\d+(\\.\\d{0,2})?")){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("服务费格式需要是数值，两位小数点！");
        }else if (params.get("serviceFee").toString().length() > 15){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("服务费格式长度不能大于15");
        }
        if (params.get("applyRequire").toString().length() > 200){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("申请需求长度不允许超过200个字符,保存失败!");
        }
        if (params.get("remark").toString().length() > 200){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("A+备注长度不允许超过200个字符,保存失败!");
        }

        tpAplusSq.setVgsBm(params.get("vgsBm").toString());
        tpAplusSq.setVgsJc(params.get("vgsJc").toString());
        tpAplusSq.setVgsMc(params.get("vgsMc").toString());
        tpAplusSq.setCode(params.get("code").toString());
        tpAplusSq.setName(params.get("name").toString());
        tpAplusSq.setCodeMerge(params.get("codeMerge").toString());
        tpAplusSq.setPlatform(params.get("platform").toString());
        tpAplusSq.setRegionName(params.get("regionName").toString());
        tpAplusSq.setCountryName(params.get("countryName").toString());
        tpAplusSq.setBoutiqueId(Long.valueOf(params.get("boutiqueId").toString()));
        tpAplusSq.setFilePath(params.get("filePath").toString());
        tpAplusSq.setServiceFee(new BigDecimal(params.get("serviceFee").toString()));
        tpAplusSq.setApplyRequire(params.get("applyRequire").toString());
        tpAplusSq.setRemark(params.get("remark").toString());
        tpAplusSq.setUpdateTime(new Date());
        tpAplusSqMapper.update(tpAplusSq);
        return R.ok(AddDto.gotoEdit("/web/business/tpAplusSq/toEdit?bid=" + tpAplusSq.getBid()));
    }

    /**
     * 删除
     */
    @Override
    public R delete(Long id) {
        TpAplusSq tpAplusSq = new TpAplusSq().setId(id).queryFirst();
        if (tpAplusSq == null){
            R.error("A+申请不存在!");
        }
        tpAplusSqMapper.deleteTrue(id);
        return R.ok("删除成功!");
    }

    @Override
    public String checkParams(Map<String, Object> params, Long menuId) throws Exception {
        return null;
    }

    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R flowPass(Long id, String loginUserId) throws Exception {

        TpAplusSq entity = new TpAplusSq().setId(id).queryFirst();

        if (entity == null) {
            return R.error("该A+申请单不存在,请核实后再操作!");
        }
        String bid = entity.getBid();
        YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();

        // 若流程是初始化状态，需要验证账户金额
        if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
            //获取公司编码
            String vGsBm = entity.getVgsBm();
            //根据公司编码获取对应的实时资金表信息
            TcwAccountCountForCompany account = new TcwAccountCountForCompany().setVGsBm(vGsBm).queryFirst();
            //获取对应的实时资金信息
            BigDecimal amountAble = account.getFJe().add(account.getFFzEd()).subtract(account.getFDjJe());
            //判断金额是否大于公司的实时资金
            if (amountAble.compareTo(entity.getServiceFee().negate()) < 0) {
                return R.error("【" + vGsBm + "】账户可用余额不足，无法流转");
            }
        }
        try {
            Flow f = yspTaskService.flowPass(bid, loginUserId);
            if (f.getCode() == Flow.Code.FAILED.value) {
                return R.error(f.getMsg());
            } else {
                // 若是制单流转，冻结账户
                if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
                    //获取公司编码
                    String vGsBm = entity.getVgsBm();
                    //获取要冻结的金额数
                    BigDecimal amount = entity.getServiceFee();
                    //冻结
                    tcwAccountCountForCompanyService.frozen(
                            vGsBm,
                            amount,
                            TcwOperateFrozenRunningEnum.DocumentType.TP_AplusSq.value,
                            entity.getId(),
                            entity.getBid(),
                            null);
                }

                //若是制单完成
                if (f.getState() == Flow.State.FINISH.value) {
                    flowFinish(entity);
                }

                return R.ok();
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("服务器正在开小差，请联系客服");
        }
    }

    @Override
    public R flowRefuse(Long id, String reason, String loginUserId) throws Exception {

        TpAplusSq entity = new TpAplusSq().setId(id).queryFirst();
        String bid = entity.getBid();

        R r = yspTaskService.flowRefuse(bid, reason, loginUserId);

        if (r.getCode() == R.Code.SUCCESS.value) {
            YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
            // 若退回到制单状态，则解冻账户
            if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
                //获取公司编码
                String vGsBm = entity.getVgsBm();
                //获取要解冻的金额数
                BigDecimal amount = entity.getServiceFee();
                //解冻
                tcwAccountCountForCompanyService.thaw(vGsBm, amount,
                        TcwOperateFrozenRunningEnum.DocumentType.TP_AplusSq.value,
                        entity.getId(),
                        entity.getBid(),
                        null);
            }

        }
        return r;
    }


    @Override
    public R flowInit(Long id, String reason, String loginUserId) throws Exception {

        TpAplusSq entity = new TpAplusSq().setId(id).queryFirst();
        String bid = entity.getBid();

        R r = yspTaskService.flowInit(bid, reason, loginUserId);

        if (r.getCode() == R.Code.SUCCESS.value) {
            YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
            // 若退回到制单状态，则解冻账户
            if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
                //获取公司编码
                String vGsBm = entity.getVgsBm();
                //获取要解冻的金额数
                BigDecimal amount = entity.getServiceFee();
                //解冻
                tcwAccountCountForCompanyService.thaw(vGsBm, amount,
                        TcwOperateFrozenRunningEnum.DocumentType.TP_AplusSq.value,
                        entity.getId(),
                        entity.getBid(),
                        null);
            }

        }
        return r;
    }


    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R flowFinish(TpAplusSq entity) throws Exception {
        Date date = new Date();
        entity.setEffectStock(1);
        entity.setUpdateTime(date);
        tpAplusSqMapper.update(entity);
        TpBoutiqueSiteDetail tpBoutiqueSiteDetail = new TpBoutiqueSiteDetail().setId(entity.getBoutiqueId()).queryFirst();
        if (tpBoutiqueSiteDetail == null){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("该精品库数据不存在,请核实后再操作!");
        }
        TpAplusFile tpAplusFile = new TpAplusFile()
                .setBoutiqueSiteDetailId(tpBoutiqueSiteDetail.getId()).setVgsBm(entity.getVgsBm())
                .queryFirst();

        int fileSize = 0;
        String contentType = "";
        String fileName = "";
        try {
            // 线上文件URL
            URL url = new URL(entity.getFilePath());
            URLConnection connection = url.openConnection();

            // 设置通用的请求属性
            connection.setRequestProperty("User-Agent", "Mozilla/5.0");

            // 建立连接
            connection.connect();

            // 获取内容长度，即文件大小
            fileSize = connection.getContentLength();

            // 获取内容类型
            contentType = connection.getContentType();

            // 获取文件名称（从URL中解析）
            fileName = url.getFile();
            int index = fileName.lastIndexOf('/');
            if (index >= 0) {
                fileName = fileName.substring(index + 1);
            }
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            R.error("附件获取失败!");
        }

        //获取附件的信息
        if (tpAplusFile == null){
            //新增
            TpAplusFile tpAplusFile1 = new TpAplusFile();
            tpAplusFile1.setBoutiqueId(tpBoutiqueSiteDetail.getBoutiqueId());
            tpAplusFile1.setCode(entity.getCode());
            tpAplusFile1.setBoutiqueSiteDetailId(tpBoutiqueSiteDetail.getId());
            tpAplusFile1.setVgsBm(entity.getVgsBm());
            tpAplusFile1.setFileName(fileName);
            tpAplusFile1.setFilePath(entity.getFilePath());
            tpAplusFile1.setFileType(contentType);
            tpAplusFile1.setFileSize(String.valueOf(fileSize));
            tpAplusFile1.setFileSizeUnit("bytes");
            tpAplusFile1.setStatus(0);
            tpAplusFileMapper.insert(tpAplusFile1);
        }else {
            //修改
            tpAplusFile.setFileName(fileName);
            tpAplusFile.setFilePath(entity.getFilePath());
            tpAplusFile.setFileType(contentType);
            tpAplusFile.setFileSize(String.valueOf(fileSize));
            tpAplusFile.setFileSizeUnit("bytes");
            tpAplusFileMapper.update(tpAplusFile);
        }

        //查询产品运营公司
        Map<String, Object> thrOperateCompanyApply = new ThrOperateCompanyApply()
                .addLeftJoin("TS_AccountBandDept t2 on t2.VGsBm = A.VGsBm")
                .where("t2.AccountId = 'CPKF'")
                .queryFirstMap();
        if (thrOperateCompanyApply == null){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("产品运营公司不存在,核实后再操作!");
        }

        //划出流水
        tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompany(
                entity.getVgsBm(),thrOperateCompanyApply.get("vgsbm").toString(), TransactionTypeEnum.BusinessType.TP_AplusSq.name,entity.getServiceFee().negate(),
                date,date,"美工费用，A+申请单:" + entity.getBid() +"，商品编码:" + entity.getCode(),
                entity.getBid(),null);

        //划入流水
        tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompany(
                thrOperateCompanyApply.get("vgsbm").toString(),entity.getVgsBm(),TransactionTypeEnum.BusinessType.TP_AplusSq.name,entity.getServiceFee(),
                date,date,"美工费用，A+申请单:" + entity.getBid() +"，商品编码:" + entity.getCode(),
                entity.getBid(),null);
        //解冻账户
        //获取公司编码
        String vGsBm = entity.getVgsBm();
        //获取要解冻的金额数
        BigDecimal amount = entity.getServiceFee();
        //解冻
        tcwAccountCountForCompanyService.thaw(vGsBm, amount,
                TcwOperateFrozenRunningEnum.DocumentType.TP_AplusSq.value,
                entity.getId(),
                entity.getBid(),
                null);
        return R.ok();
    }



    //获取列表数据
    @Override
    @Transactional
    public Map<String,Object> getExtraParam( String bid) throws Exception{
        Map<String, Object> entity = new TpAplusSq().setBid(bid).queryFirstMap();

        YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();

        entity.put("updateTime1", DateUtil.getYYYY_MM_DD_HH_mm_ss(ysProcInst.getUpdateTime()));
        return entity;
    }


}
